package com.utils;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.io.FileNotFoundException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class BeanFactoryUtil {

    //模拟IOC容器
    Map map = new HashMap<String, Object>();

    public BeanFactoryUtil(String xml) throws FileNotFoundException {
        parseXml(xml);
    }

    public void parseXml(String xml) throws FileNotFoundException {
        //获取类路径下的xml文件
        File file = new File(this.getClass().getClassLoader().getResource(xml).getPath());
        SAXReader reader = new SAXReader();
        try {
            //获取xml文档
            Document document = reader.read(file);
            //获取根元素
            Element rootElement = document.getRootElement();
            //遍历根元素下的元素,也就是第一层子标签
            for (Iterator<Element> itFirst = rootElement.elementIterator(); itFirst.hasNext(); ) {
                Element elementFistChild = itFirst.next();
                // do something
                /*
                第一步实例化对象
                 */
                //获取属性id中的填写的信息
                Attribute attributeId = elementFistChild.attribute("id");
                String beanName = attributeId.getValue();
                //获取属性class属性中的信息
                Attribute aClass = elementFistChild.attribute("class");
                String clazzName = aClass.getValue();
                Class clazz = Class.forName(clazzName);
                //实例化
                Object instance = clazz.newInstance();
                /*
                    第二步维护依赖
                    判断这个对象是否有依赖 （判断是否有property，判断类是否有属性）
                    如果有就注入d
                 */
                //第二层
                for (Iterator<Element> itSecon = elementFistChild.elementIterator(); itSecon.hasNext(); ) {
                    Element elementSecondChild = itSecon.next();
                    if (elementSecondChild.getName().equals("property")) {
                        String refValue = elementSecondChild.attribute("ref").getValue();
                        Object injetObject = map.get(refValue);//需要注入的对象
                        String nameValue = elementSecondChild.attribute("name").getValue();
                        Field field = clazz.getDeclaredField(nameValue);
                        field.setAccessible(true);
                        field.set(instance, injetObject);
                    }
                }
                map.put(beanName, instance);//放入IOC容器中
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public Object getBean(String beanName) {
        return map.get(beanName);
    }
}
